import { gkhCreate } from './tools';

function BoxTemplate(node, mode, parentComponent) {
    const me = this;
    this.parentComponent = parentComponent;
    this.name = 'boxTemplate';
    const container = gkhCreate('div', {
        style: {
            position: 'relative',
            border: '1px solid black',
            width: '50px',
            height: '50px'
        }
    });
    let nodeInfo;
    let parentNodeInfo;
    let parentNode = node;
    let mouseDown = false;
    let downPoint;
    let positionPoint;
    let hasChange = false;
    let handle = 0; // 1:移动盒子 2：改变盒子宽度向右 3：改变盒子高度向下 4：改变盒子宽度向左 5：改变盒子高度向上
    let precision = 5;
    let round;
    let containerInfo;
    function getNodeInfo(ele) {
        const { pageXOffset, pageYOffset } = window;
        const { x, y, top, left, bottom, right, width, height } = ele.getBoundingClientRect();
        return {
            x: x + pageXOffset,
            left: left + pageXOffset,
            right: right + pageXOffset,
            y: y + pageYOffset,
            top: top + pageYOffset,
            bottom: bottom + pageYOffset,
            width,
            height,
        }
    }
    function change() {
        hasChange = false;
        nodeInfo = getNodeInfo(container);
    }

    function onMouseDown(e) {
        mouseDown = true;
        const { pageXOffset, pageYOffset } = window;
        downPoint = {
            x: e.clientX + pageXOffset,
            y: e.clientY + pageYOffset
        };
        change();
        parentNodeInfo = getNodeInfo(parentNode);
        const { left, right, top, bottom, width, height } = parentNodeInfo;
        const pleft = container.style.left ? parseFloat(container.style.left) : 0;
        const ptop = container.style.top ? parseFloat(container.style.top) : 0;
        positionPoint = {
            x: nodeInfo.x - pleft,
            y: nodeInfo.y - ptop,
        }
        round = {
            minX: left - positionPoint.x,
            maxX: left - positionPoint.x + width - nodeInfo.width,
            minY: top - positionPoint.y,
            maxY: top - positionPoint.y + height - nodeInfo.height
        }
    }

    function onMouseMove(e) {
        const { pageXOffset, pageYOffset } = window;
        const clientX = pageXOffset + e.clientX;
        const clientY = pageYOffset + e.clientY;
        const { left, top, right, bottom, width, height } = nodeInfo;
        if (mouseDown) {
            switch (handle) {
                case 1: {
                    const dx = clientX - positionPoint.x;
                    const dy = clientY - positionPoint.y;
                    if (round.minX < dx && dx < round.maxX && round.minY < dy && dy < round.maxY) {
                        container.style.left = dx.toString().concat('px');
                        container.style.top = dy.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 6: {
                    const dx = clientX - width - positionPoint.x;
                    const dy = clientY - positionPoint.y;
                    if (round.minX < dx && dx < round.maxX && round.minY < dy && dy < round.maxY) {
                        container.style.left = dx.toString().concat('px');
                        container.style.top = dy.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 7: {
                    const dx = clientX - positionPoint.x;
                    const dy = clientY - height - positionPoint.y;
                    if (round.minX < dx && dx < round.maxX && round.minY < dy && dy < round.maxY) {
                        container.style.left = dx.toString().concat('px');
                        container.style.top = dy.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 8: {
                    const dx = clientX - width - positionPoint.x;
                    const dy = clientY - height - positionPoint.y;
                    if (round.minX < dx && dx < round.maxX && round.minY < dy && dy < round.maxY) {
                        container.style.left = dx.toString().concat('px');
                        container.style.top = dy.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 2: {
                    const dw = width + clientX - downPoint.x;
                    if (dw > 0 && dw < parentNodeInfo.width) {
                        container.style.width = dw.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 3: {
                    const dh = height + clientY - downPoint.y;
                    if (dh > 0 && dh < parentNodeInfo.height) {
                        container.style.height = dh.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 4: {
                    const dx = nodeInfo.x - parentNodeInfo.x + clientX - downPoint.x;
                    const dw = width + downPoint.x - clientX;
                    if (dw > 0 && dw < parentNodeInfo.width) {
                        container.style.left = dx.toString().concat('px');
                        container.style.width = dw.toString().concat('px');
                    }
                    hasChange = true;
                } break;
                case 5: {
                    const dy = nodeInfo.y - parentNodeInfo.y + clientY - downPoint.y;
                    const dh = height + downPoint.y - clientY;
                    if (dh > 0 && dh < parentNodeInfo.height) {
                        container.style.top = dy.toString().concat('px');
                        container.style.height = dh.toString().concat('px');
                    }
                    hasChange = true;
                } break;
            }
        } else {
            let className = container.getAttribute('class');
            className = className ? className : '';
            className = className.replace(' gkh-box-move', '');
            className = className.replace(' gkh-box-eresize', '');
            className = className.replace(' gkh-box-nresize', '');
            handle = 0;
            // 触发移动标识
            if (clientX - containerInfo.left < precision && clientX > containerInfo.left && clientY > containerInfo.top && clientY - containerInfo.top < precision) {
                className = className.concat(' gkh-box-move');
                handle = 1;
            } else if (containerInfo.right - clientX < precision && clientX < containerInfo.right && clientY > containerInfo.top && clientY - containerInfo.top < precision) {
                className = className.concat(' gkh-box-move');
                handle = 6;
            } else if (clientX - containerInfo.left < precision && clientX > containerInfo.left && clientY < containerInfo.bottom && containerInfo.bottom - clientY < precision) {
                className = className.concat(' gkh-box-move');
                handle = 7;
            } else if (containerInfo.right - clientX < precision && clientX < containerInfo.right && clientY < containerInfo.bottom && containerInfo.bottom - clientY < precision) {
                className = className.concat(' gkh-box-move');
                handle = 8;
            } else if (containerInfo.right - clientX < precision && containerInfo.right > clientX) { // 触发宽度修改标识 向右
                className = className.concat(' gkh-box-eresize');
                handle = 2;
            } else if (containerInfo.bottom - clientY < precision && containerInfo.bottom > clientY) { // 触发高度修改标识 向下
                className = className.concat(' gkh-box-nresize');
                handle = 3;
            } else if (clientX - containerInfo.left < precision && containerInfo.left < clientX) { // 触发宽度修改标识 向左
                className = className.concat(' gkh-box-eresize');
                handle = 4;
            } else if (clientY - containerInfo.top < precision && containerInfo.top < clientY) { // 触发高度修改标识 向上
                className = className.concat(' gkh-box-nresize');
                handle = 5;
            }
            container.setAttribute('class', className);
        }
    }

    function onMouseUp() {
        mouseDown = false;
        if (hasChange) {
            change();
        }
    }
    this.render = function (node, templateData) {
        if (node instanceof Node) {
            parentNode = node;
            node.appendChild(container);
            change();
            containerInfo = getNodeInfo(container);
            positionPoint = nodeInfo;
            if ((mode == 1 || mode == 2) && node) {
                container.onmousedown = onMouseDown;
                container.onmouseenter = function(){
                    containerInfo = getNodeInfo(container);
                };
                node.addEventListener('mousemove', onMouseMove);
                node.addEventListener('mouseup', onMouseUp);
            }
        }
        container.innerHTML = "";
    }
    this.render(node);

    function getBoxTemplateData(){

    }
    
    this.addItem = function(){

    }
}

export default BoxTemplate;